package com.imonsoft.sqm.service.business.ipic_system;

import java.util.List;
import java.util.Map;

import com.imonsoft.common.exception.SystemException;
import com.imonsoft.sqm.dao.business.ipic_system.ClaimViewDAO;
import com.imonsoft.sqm.pojo.basedata.IpicRule;
import com.imonsoft.sqm.pojo.business.ipic_system.*;
import com.imonsoft.sqm.service.basedata.IpicRuleService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.imonsoft.common.constant.ConstantSqm;
import com.imonsoft.sqm.dao.business.ipic_system.IncomingDAO;

@Service("ipicService")
public class IPICServiceImpl implements IPICService {
	protected final Log logger = LogFactory.getLog(getClass());
    @Autowired
    private IpicRuleService ipicRuleService;
    @Autowired
    private IncomingDAO incomingDAO;
    @Autowired
    private ClaimViewDAO claimViewDAO;

    @Override
    public double getAmountNotQualifiedMonth(Map<String,Object> searchMap) {
        ClaimViewExample example=new ClaimViewExample();
        ClaimViewExample.Criteria criteria=example.createCriteria();
        if(null!=searchMap){
            if(null!=searchMap.get("supplierId")){
                criteria.andSupplierIdEqualTo((Long)searchMap.get("supplierId"));
            }
            if(null!=searchMap.get("partId")){
                criteria.andPartIdEqualTo((Long)searchMap.get("partId"));
            }
            if(null!=searchMap.get("type")){
                criteria.andTypeEqualTo((String)searchMap.get("type"));
            }
            if(null!=searchMap.get("claimType")){
                criteria.andClaimTypeEqualTo((String)searchMap.get("claimType"));
            }
            /*if(null!=searchMap.get("year") && null!=searchMap.get("month")){
                int year=Integer.parseInt((String)searchMap.get("year"));
                int month=Integer.parseInt((String)searchMap.get("month"));
                Date yearMonthStart= DateUtil.getYearMonthStart(year,month);
                Date yearNextMonthStart= DateUtil.getYearMonthEnd(year,month);
                criteria.andStartDateBetween(yearMonthStart,yearNextMonthStart);
            }*/
            if(null!=searchMap.get("year")){
                criteria.andYearEqualTo(Integer.parseInt((String) searchMap.get("year")));
            }
            if(null!=searchMap.get("month")){
                criteria.andMonthEqualTo(Integer.parseInt((String) searchMap.get("month")));
            }
        }
        List<ClaimView> claimViewList=claimViewDAO.selectClaimViewByExample(example);

        double amount=0.0;
        if(null!=claimViewList){
            for(ClaimView view:claimViewList){
                if(null!=view.getAmountUnqualified()){
                    amount=amount+view.getAmountUnqualified();
                }
            }
        }
        return amount;
    }

    @Override
    public double getAmountNotQualifiedAccumulate(Map<String,Object> searchMap) {
        ClaimViewExample example = new ClaimViewExample();
        ClaimViewExample.Criteria criteria = example.createCriteria();
        if(null!=searchMap){
            if(null!=searchMap.get("supplierId")){
                criteria.andSupplierIdEqualTo((Long)searchMap.get("supplierId"));
            }
            if(null!=searchMap.get("partId")){
                criteria.andPartIdEqualTo((Long)searchMap.get("partId"));
            }
            if(null!=searchMap.get("type")){
                criteria.andTypeEqualTo((String)searchMap.get("type"));
            }
            if(null!=searchMap.get("claimType")){
                criteria.andClaimTypeEqualTo((String)searchMap.get("claimType"));
            }
            if(null!=searchMap.get("year")){
                criteria.andYearEqualTo(Integer.parseInt((String)searchMap.get("year")));
            }
            /*if(null!=searchMap.get("year") && null!=searchMap.get("month")){
                int year=Integer.parseInt((String)searchMap.get("year"));
                int month=Integer.parseInt((String)searchMap.get("month"));
                Date yearStart= DateUtil.getYearStart(year);
                Date nextMonthStart= DateUtil.getYearMonthEnd(year,month);
                criteria.andStartDateBetween(yearStart,nextMonthStart);
            }*/
            if(null!=searchMap.get("month")){
                criteria.andMonthLessThanOrEqualTo(Integer.parseInt((String) searchMap.get("month")));
            }
        }
        List<ClaimView> claimViewList=claimViewDAO.selectClaimViewByExample(example);

        double amount=0.0;
        if(null!=claimViewList){
            for(ClaimView view:claimViewList){
                if(null!=view.getAmountUnqualified()){
                    amount=amount+view.getAmountUnqualified();
                }
            }
        }
        return amount;
    }

    @Override
    public double getAmountNotQualifiedRolling(Map<String, Object> searchMap) {
        ClaimViewExample example = new ClaimViewExample();
        ClaimViewExample.Criteria criteria = example.createCriteria();
        if(null!=searchMap){
            if(null!=searchMap.get("supplierId")){
                criteria.andSupplierIdEqualTo((Long)searchMap.get("supplierId"));
            }
            if(null!=searchMap.get("partId")){
                criteria.andPartIdEqualTo((Long)searchMap.get("partId"));
            }
            if(null!=searchMap.get("type")){
                criteria.andTypeEqualTo((String)searchMap.get("type"));
            }
            if(null!=searchMap.get("claimType")){
                criteria.andClaimTypeEqualTo((String)searchMap.get("claimType"));
            }
            if(null!=searchMap.get("year")){
                criteria.andYearEqualTo(Integer.parseInt((String)searchMap.get("year")));
            }
            if(null!=searchMap.get("monthBegin") && null!=searchMap.get("monthEnd")){
                criteria.andMonthBetween(Integer.parseInt((String) searchMap.get("monthBegin")),
                        Integer.parseInt((String) searchMap.get("monthEnd")));
            }
        }
        List<ClaimView> claimViewList=claimViewDAO.selectClaimViewByExample(example);

        double amount=0.0;
        if(null!=claimViewList){
            for(ClaimView view:claimViewList){
                if(null!=view.getAmountUnqualified()){
                    amount=amount+view.getAmountUnqualified();
                }
            }
        }
        return amount;
    }

    @Override
    public void getMonthData(Map<String, Object> searchMap,Map<String,Object> resultMap) {
        ClaimViewExample example=new ClaimViewExample();
        ClaimViewExample.Criteria criteria=example.createCriteria();
        if(null!=searchMap){
            if(null!=searchMap.get("supplierId")){
                criteria.andSupplierIdEqualTo((Long)searchMap.get("supplierId"));
            }
            if(null!=searchMap.get("partId")){
                criteria.andPartIdEqualTo((Long)searchMap.get("partId"));
            }
            if(null!=searchMap.get("type")){
                criteria.andTypeEqualTo((String)searchMap.get("type"));
            }
            if(null!=searchMap.get("claimType")){
                criteria.andClaimTypeEqualTo((String)searchMap.get("claimType"));
            }
            if(null!=searchMap.get("year")){
                criteria.andYearEqualTo(Integer.parseInt((String) searchMap.get("year")));
            }
            if(null!=searchMap.get("month")){
                criteria.andMonthEqualTo(Integer.parseInt((String) searchMap.get("month")));
            }
        }
        List<ClaimView> claimViewList=claimViewDAO.selectClaimViewByExample(example);

        double amountUnqualified=0.0;
        double ipicValueTotal=0.0;
        long claimQuantity=0l;
        if(null!=claimViewList){
            for(ClaimView view:claimViewList){
                if(null!=view.getAmountUnqualified()){
                    amountUnqualified=amountUnqualified+view.getAmountUnqualified();
                }
                if(null!=view.getIpicValueTotal()){
                    ipicValueTotal=ipicValueTotal+view.getIpicValueTotal();
                }
                if(null!=view.getClaimQuantity()){
                    claimQuantity=claimQuantity+view.getClaimQuantity();
                }
            }
        }
        resultMap.put("amountUnqualified",amountUnqualified); //不合格数量
        resultMap.put("ipicValueTotal",ipicValueTotal); //IPICValueTotal即C、P、R、D、Ca相乘结果，再进行累计
        resultMap.put("claimQuantity",claimQuantity); //投诉个数
    }
    @Override
    public void getAccumulateData(Map<String, Object> searchMap,Map<String,Object> resultMap) {
        ClaimViewExample example = new ClaimViewExample();
        ClaimViewExample.Criteria criteria = example.createCriteria();
        if(null!=searchMap){
            if(null!=searchMap.get("supplierId")){
                criteria.andSupplierIdEqualTo((Long)searchMap.get("supplierId"));
            }
            if(null!=searchMap.get("partId")){
                criteria.andPartIdEqualTo((Long)searchMap.get("partId"));
            }
            if(null!=searchMap.get("type")){
                criteria.andTypeEqualTo((String)searchMap.get("type"));
            }
            if(null!=searchMap.get("claimType")){
                criteria.andClaimTypeEqualTo((String)searchMap.get("claimType"));
            }
            if(null!=searchMap.get("year")){
                criteria.andYearEqualTo(Integer.parseInt((String)searchMap.get("year")));
            }
            if(null!=searchMap.get("month")){
                criteria.andMonthLessThanOrEqualTo(Integer.parseInt((String) searchMap.get("month")));
            }
        }
        List<ClaimView> claimViewList=claimViewDAO.selectClaimViewByExample(example);

        double amountUnqualified=0.0;
        double ipicValueTotal=0.0;
        long claimQuantity=0l;
        if(null!=claimViewList){
            for(ClaimView view:claimViewList){
                if(null!=view.getAmountUnqualified()){
                    amountUnqualified=amountUnqualified+view.getAmountUnqualified();
                    ipicValueTotal=ipicValueTotal+view.getIpicValueTotal();
                    claimQuantity=claimQuantity+view.getClaimQuantity();
                }
            }
        }
        resultMap.put("amountUnqualified",amountUnqualified);
        resultMap.put("ipicValueTotal",ipicValueTotal);
        resultMap.put("claimQuantity",claimQuantity);
    }

    @Override
    public double getIncomingAmountMonth(Map<String,Object> searchMap) {
        IncomingExample example = new IncomingExample();
        IncomingExample.Criteria criteria = example.createCriteria();
        criteria.andStateNotEqualTo(ConstantSqm.STATUS_DELETE);
        if(null!=searchMap){
            if(null!=searchMap.get("supplierId")){
                criteria.andSupplierIdEqualTo((Long)searchMap.get("supplierId"));
            }
            if(null!=searchMap.get("partId")){
                criteria.andPartIdEqualTo((Long)searchMap.get("partId"));
            }
            if(null!=searchMap.get("year")){
                criteria.andYearEqualTo((String)searchMap.get("year"));
            }
            if(null!=searchMap.get("month")){
                criteria.andMonthEqualTo((String) searchMap.get("month"));
            }
        }
        List<Incoming> incomingList=incomingDAO.selectIncomingByExample(example);

        double amount=0.0;
        if(null!=incomingList){
            for(Incoming incoming:incomingList){
                if(null!=incoming.getAmount()){
                    amount=amount+incoming.getAmount();
                }
            }
        }
        return amount;
    }
    @Override
    public double getIncomingAmountAccumulate(Map<String,Object> searchMap) {
        IncomingExample example = new IncomingExample();
        IncomingExample.Criteria criteria = example.createCriteria();
        criteria.andStateNotEqualTo(ConstantSqm.STATUS_DELETE);
        if(null!=searchMap){
            if(null!=searchMap.get("supplierId")){
                criteria.andSupplierIdEqualTo((Long)searchMap.get("supplierId"));
            }
            if(null!=searchMap.get("partId")){
                criteria.andPartIdEqualTo((Long)searchMap.get("partId"));
            }
            if(null!=searchMap.get("year")){
                criteria.andYearEqualTo((String)searchMap.get("year"));
            }
            if(null!=searchMap.get("month")){
                criteria.andMonthLessThanOrEqualTo((String) searchMap.get("month"));
            }
        }
        List<Incoming> incomingList=incomingDAO.selectIncomingByExample(example);

        double amount=0.0;
        if(null!=incomingList){
            for(Incoming incoming:incomingList){
                if(null!=incoming.getAmount()){
                    amount=amount+incoming.getAmount();
                }
            }
        }
        return amount;
    }

    @Override
    public double getIncomingAmountRolling(Map<String, Object> searchMap) {
        IncomingExample example = new IncomingExample();
        IncomingExample.Criteria criteria = example.createCriteria();
        criteria.andStateNotEqualTo(ConstantSqm.STATUS_DELETE);
        if(null!=searchMap){
            if(null!=searchMap.get("supplierId")){
                criteria.andSupplierIdEqualTo((Long)searchMap.get("supplierId"));
            }
            if(null!=searchMap.get("partId")){
                criteria.andPartIdEqualTo((Long)searchMap.get("partId"));
            }
            if(null!=searchMap.get("year")){
                criteria.andYearEqualTo((String)searchMap.get("year"));
            }
            if(null!=searchMap.get("monthBegin") && null!=searchMap.get("monthEnd")){
                criteria.andMonthBetween((String) searchMap.get("monthBegin"),
                        (String) searchMap.get("monthEnd"));
            }
        }
        List<Incoming> incomingList=incomingDAO.selectIncomingByExample(example);

        double amount=0.0;
        if(null!=incomingList){
            for(Incoming incoming:incomingList){
                if(null!=incoming.getAmount()){
                    amount=amount+incoming.getAmount();
                }
            }
        }
        return amount;
    }

    private  List<IpicRule> ppmIpicRuleList;
    private  List<IpicRule> claimValueIpicRuleList;
    private  List<IpicRule> claimQuantityIpicRuleList;

    private void getIPICRule(){
        //得到IPIC计算规则
        if(ppmIpicRuleList==null){
            ppmIpicRuleList=ipicRuleService.findIpicRuleByType(ConstantSqm.IPIC_RULE_TYPE_PPM);
        }
        if(claimValueIpicRuleList==null){
            claimValueIpicRuleList=ipicRuleService.findIpicRuleByType(ConstantSqm.IPIC_RULE_TYPE_CLAIM_VALUE);
        }
        if(claimQuantityIpicRuleList==null){
            claimQuantityIpicRuleList=ipicRuleService.findIpicRuleByType(ConstantSqm.IPIC_RULE_TYPE_CLAIM_QUANTITY);
        }
    }

    @Override
    public void calIPICMonthData(Map<String, Object> searchMap, Map<String, Object> resultMap) {
        if(null==searchMap || null==resultMap){
            throw new SystemException(ConstantSqm.DATA_ERROR);
        }
        getIPICRule();
        getMonthData(searchMap, resultMap);
        //根据IPIC计算规则，计算PPM
        double totalNum= getIncomingAmountMonth(searchMap);
        double ppm=0.0;
        if(totalNum!=0.0){
            ppm=((Double)resultMap.get("amountUnqualified")*1000000.0)/totalNum;
        }
        //计算PIC
        double ipicValueTotal=(Double)resultMap.get("ipicValueTotal");
        long claimQuantity=(Long)resultMap.get("claimQuantity");
        int valueP=0,valueI=0,valueC=0;
        for(IpicRule ipicRule:ppmIpicRuleList){
            if(ppm>=ipicRule.getMin() && ppm<=ipicRule.getMax()){
                valueP=ipicRule.getValue();
            }
        }
        for(IpicRule ipicRule:claimValueIpicRuleList){
            if(ipicValueTotal>=ipicRule.getMin() && ipicValueTotal<=ipicRule.getMax()){
                valueI=ipicRule.getValue();
            }
        }
        for(IpicRule ipicRule:claimQuantityIpicRuleList){
            if(claimQuantity>=ipicRule.getMin() && claimQuantity<=ipicRule.getMax()){
                valueC=ipicRule.getValue();
            }
        }
        resultMap.put("ppm",ppm);
        resultMap.put("valueP",valueP);
        resultMap.put("valueI",valueI);
        resultMap.put("valueC",valueC);
        resultMap.put("ipicMonth",valueP+valueI+valueC);
    }
    @Override
    public void calPMCPMonthData(Map<String, Object> searchMap, Map<String, Object> resultMap) {
        if(null==searchMap || null==resultMap){
            throw new SystemException(ConstantSqm.DATA_ERROR);
        }
        getIPICRule();
        getMonthData(searchMap, resultMap);
        //根据IPIC计算规则，计算PPM
        double totalNum= getIncomingAmountMonth(searchMap);
        double ppm=0.0;
        if(totalNum!=0.0){
            ppm=((Double)resultMap.get("amountUnqualified")*1000000.0)/totalNum;
        }
        //计算PC,PMCP没有I
        long claimQuantity=(Long)resultMap.get("claimQuantity");
        int valueP=0,valueC=0;
        for(IpicRule ipicRule:ppmIpicRuleList){
            if(ppm>=ipicRule.getMin() && ppm<=ipicRule.getMax()){
                valueP=ipicRule.getValue();
            }
        }
        for(IpicRule ipicRule:claimQuantityIpicRuleList){
            if(claimQuantity>=ipicRule.getMin() && claimQuantity<=ipicRule.getMax()){
                valueC=ipicRule.getValue();
            }
        }
        resultMap.put("ppm",ppm);
        resultMap.put("valueP",valueP);
        resultMap.put("valueC",valueC);
        resultMap.put("ipicMonth",valueP+valueC);
    }




    public void calPPMMonthData(Map<String,Object> searchMap,Map<String,Object> resultMap){
        if(null==searchMap || null==resultMap){
            throw new SystemException(ConstantSqm.DATA_ERROR);
        }
        double totalNumM= getIncomingAmountMonth(searchMap);
        searchMap.put("claimType", ConstantSqm.CLAIM_TYPE_TECHNICAL);
        double quantityTM= getAmountNotQualifiedMonth(searchMap);
        searchMap.put("claimType", ConstantSqm.CLAIM_TYPE_LOGISTIC);
        double quantityLM= getAmountNotQualifiedMonth(searchMap);
        searchMap.remove("claimType");
        double ppmTM=0.0;
        double ppmLM=0.0;
        double ppmM=0.0;
        if(totalNumM!=0.0){
            ppmTM=(quantityTM*1000000.0)/totalNumM;
            ppmLM=(quantityLM*1000000.0)/totalNumM;
            ppmM=ppmTM+ppmLM;
        }
        resultMap.put("totalNumM",totalNumM);
        resultMap.put("quantityTM",quantityTM);
        resultMap.put("quantityLM",quantityLM);
        resultMap.put("ppmTM",ppmTM);
        resultMap.put("ppmLM",ppmLM);
        resultMap.put("ppmM",ppmM);
    }
    public void calPPMAccumulateData(Map<String,Object> searchMap,Map<String,Object> resultMap){
        if(null==searchMap || null==resultMap){
            throw new SystemException(ConstantSqm.DATA_ERROR);
        }
        double totalNumA= getIncomingAmountAccumulate(searchMap);
        searchMap.put("claimType", ConstantSqm.CLAIM_TYPE_TECHNICAL);
        double quantityTA= getAmountNotQualifiedAccumulate(searchMap);
        searchMap.put("claimType", ConstantSqm.CLAIM_TYPE_LOGISTIC);
        double quantityLA= getAmountNotQualifiedAccumulate(searchMap);
        searchMap.remove("claimType");
        double ppmTA=0.0;
        double ppmLA=0.0;
        double ppmA=0.0;
        if(totalNumA!=0.0){
            ppmTA=(quantityTA*1000000.0)/totalNumA;
            ppmLA=(quantityLA*1000000.0)/totalNumA;
            ppmA=ppmTA+ppmLA;
        }
        resultMap.put("totalNumA",totalNumA);
        resultMap.put("quantityTA",quantityTA);
        resultMap.put("quantityLA",quantityLA);
        resultMap.put("ppmTA",ppmTA);
        resultMap.put("ppmLA",ppmLA);
        resultMap.put("ppmA",ppmA);
    }
}
